:- module(dcg,['$foo$term_expansion'/2]). %% TODO: hack to make SWI happy, remove this eventually
:- op(1200,xfx,'-->').

append_args(Term, MoreArgs, TermArgs) :-
 Term =.. [Name|FirstArgs], append(FirstArgs, MoreArgs, Args), TermArgs =.. [Name|Args].

'$foo$term_expansion'((Head --> Body), (ExpandedHead :- ExpandedBody)) :-
 append_args(Head, [I, O], ExpandedHead),
 thread(I,O, Body,ExpandedBody).

thread(I,O, Var   , TODO)  :- var(Var), !, fail.
thread(I,O, []    , I=O).
thread(I,O, !     , (I=O,!)).
thread(I,O, {P}   , (I=O,P)).
thread(I,O, [X|Xs], I=K)   :- append([X|Xs], O, K).
thread(I,O, (X,Y) , (P,Q)) :- thread(I,M, X,P), thread(M,O, Y,Q).
thread(I,O, (X;Y) , (P;Q)) :- thread(I,O, X,P), thread(I,O, Y,Q).
thread(I,O, P     , Q)     :- append_args(P, [I,O], Q).
